%{
#include <string.h>
#include <stdio.h>

#define INTEGER     259
#define CHAR        260
#define FLOAT       261
#define VOID        262
#define IF          263
#define ELSE        264
#define FOR         265
#define WHILE       266
#define RETURN      267
#define AND         268
#define OR          269#define EQUALEQUAL  270
#define MINUSMINUS  271
#define PLUSPLUS    272
#define PLUSEQUAL   273
#define MULEQUAL    274
#define DIVEQUAL    275
#define MINUSEQUAL  276
#define DISCTINCT   277
#define MINEQUAL    278
#define MAYEQUAL    279#define PRINTF      280
#define ID          281     
#define CARACTER    282
#define ENTERO      283
#define REAL        284
#define LITERAL     285

typedef union
{
	char *lexema;
} YYSTYPE;

/* The semantic value of the look-ahead symbol.  */
YYSTYPE yylval;

int yywrap(void);
   

%}

digito          [0-9]
letra           [A-Za-z]
identificador   {letra}({letra}|{digito}|_)*
caracter        "'"(.|\n)+"'"
entero          (-)?{digito}+ 
real            (-)?{digito}+"."{digito}+
espacios        [ \t]+
nuevaLinea      \n

%%

"\""(.)*"\""            { yylval.lexema=strdup(yytext); return(LITERAL); };    
"/*"                    { comentario(); }
#{letra}*               {  }
"<"({letra}|.|_)*">"    { }
{espacios}              {/*No se devuelve nada*/;}
{nuevaLinea}            { yylineno++; }    
"int"                   { return(INTEGER); }
"char"                  { return(CHAR); }
"float"                 { return(FLOAT); }
"void"                  { return(VOID); }
"if"                    { return(IF); }
"else"                  { return(ELSE); }
"for"                   { return(FOR); }
"while"                 { return(WHILE); }
"return"                { return(RETURN); }
"{"                     { return('{'); }
"}"                     { return('}'); }
"("                     { return('('); }
")"                     { return(')'); }
"["                     { return('['); }
"]"                     { return(']'); }
"&&"                    { return(AND); }
"||"                    { return(OR); }
"!"                     { return('!'); }
"=="                    { return(EQUALEQUAL); }
"--"                    { return(MINUSMINUS); }
"++"                    { return(PLUSPLUS); }
"+="                    { return(PLUSEQUAL); }
"*="                    { return(MULEQUAL); }
"/="                    { return(DIVEQUAL); }
"-="                    { return(MINUSEQUAL); }
"+"                     { return('+'); }
"-"                     { return('-'); }
"%"                     { return('%'); }    
"/"                     { return('/'); }
"*"                     { return('*'); }
"!="                    { return(DISCTINCT); }
"<="                    { return(MINEQUAL); }    
">="                    { return(MAYEQUAL); }
"<"                     { return('<'); }        
">"                     { return('>'); }        
"="                     { return('='); }
";"                     { return(';'); }
","                     { return(','); }
"printf"                { return(PRINTF); }
{identificador}         { 
                            yylval.lexema=strdup(yytext);
                            return(ID);     
                        }
{caracter}              {
                            yylval.lexema=strdup(yytext);
                            return(CARACTER); 
                        }
{entero}                {
                            yylval.lexema=strdup(yytext);
                            return(ENTERO); 
                        }
{real}                  { 
                            yylval.lexema=strdup(yytext);
                            return(REAL); }
.                       { printf("Error lexico: linea %d: %c no es un caracter valido\n", yylineno, *yytext);}    

"//".*                  /* No hacer nada para los comentarios de una linea */
    
%%    
    
int yywrap(void) {
    return 1;
}


void imprimirString(char frase[]){
    int i;
    for(i=0; i<strlen(frase); i++){
        printf("%c",frase[i]);
    }
}

void error(char string[]){
    printf("Error: ");
    imprimirString(string);
    printf(" en linea %d\n",yylineno);
}

comentario()
{
    char c, prev = 0;
  
    while ((c = input()) != EOF)      /* (EOF maps to 0) */
    {
        if (c == '/' && prev == '*')
            return;
        prev = c;
    }
    error("comentario abierto");
}

int
main (int argc, char **argv)
{
    int i;

    FILE *f = fopen(argv[1], "r");
    printf("Abrio el archivo\n");
    yyrestart(f);
    printf("It did yyrestart");
    while ((i = yylex()) != 0)
        printf("%d\n", i);
    fclose(f);
}
